/*
 * FriendsServer.cpp
 *
 *  Created on: 2013. 8. 13.
 *      Author: the2
 */


#include "FriendsServer.h"
#include "Static.h"

#include <Network/Static.h>
#include <Logger/Static.h>

#include "../Proxy.h"
#include "../User.h"
#include "../Session.h"
#include "../Static.h"

#include "../NLogic/Static.h"
#include "../NLogic/SocialInfo.h"
#include "../NLogic/Buff.h"
#include "../NLogic/Reward.h"
#include "../NLogic/BackEndServerInfo.h"

#include "../NResource/Static.h"
#include "../NResource/ChargeItemResource.h"
#include "../NResource/WeeklyRewardResource.h"

#include "Static.h"

namespace ProjectZ { namespace NProxy {

void
FriendsServer::Msg::OnOpenAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	PROCESSLOG("[FRIEND] OnOpen Server IP : %s PORT : %d",
				pSession->GetNetworkPeerInfo().ip.c_str(), pSession->GetNetworkPeerInfo().port);

	Session * pLocalSession = static_cast<Session *>(pSession);
	FriendsServer * pServer = static_cast<FriendsServer *>(pLocalSession->GetOwner());
	::ProjectZ::Static::Instance()._friendServer[pServer->GetIdx()] = true;
}

void
FriendsServer::Msg::OnCloseAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	PROCESSLOG("[FRIEND] OnClose Server IP : %s PORT : %d",
								pSession->GetNetworkPeerInfo().ip.c_str(), pSession->GetNetworkPeerInfo().port);

	Session * pLocalSession = static_cast<Session *>(pSession);
	FriendsServer * pServer = static_cast<FriendsServer *>(pLocalSession->GetOwner());
	pServer->OnDisconnect();
}

void
FriendsServer::Msg::OnSocialMyInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	SocialMyInfoAck ans;
	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		::Logger::GETLOG()->ToAll(::Logger::DEBUG, "%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;
	pUser->GetSocialInfo()->GetData()->_heart_blocked = ans.heart_blocked;
	pUser->GetSocialInfo()->GetData()->_invite_blocked = ans.invite_block;
	pUser->GetSocialInfo()->GetData()->_profile_opened = ans.profile_opened;
	pUser->GetSocialInfo()->GetData()->_birthday = ans.birthday;
	pUser->GetSocialInfo()->GetData()->_gender = ans.gender;
	pUser->GetSocialInfo()->GetData()->_isBirthdayOpen = ans.birth_open;
	pUser->GetSocialInfo()->GetData()->_isGenderOpen = ans.gender_open;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << ans.result
			<< ans.seq
			<< pUser->GetUserInfo().wp_cur_week
			<< static_cast<uint8_t>(ans.heart_blocked)
			<< static_cast<uint8_t>(ans.profile_opened)
			<< static_cast<uint8_t>(ans.invite_block)
			<< static_cast<uint8_t>(ans.gender)
			<< static_cast<uint8_t>(ans.gender_open)
			<< ans.birthday.c_str()
			<< static_cast<uint8_t>(ans.birth_open);
	pAck->MakePacket(CMD_SC_SOCIAL_MYINFO);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnSocialUserSeqAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	SocialUserSeqAck ans;
	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		::Logger::GETLOG()->ToAll(::Logger::DEBUG, "%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << ans.result
			<< static_cast<uint16_t>(ans.array_social_userseq_info.size());

	auto itr = ans.array_social_userseq_info.begin();
	for(; itr != ans.array_social_userseq_info.end(); ++itr)
	{
		*pAck << itr->socialid
				<< itr->userseq
				<< static_cast<uint8_t>(itr->is_delete);
		DEBUGLOG("%s | userseq = %d\n", __FUNCTION__, itr->userseq);
	}

	pAck->MakePacket(CMD_SC_SOCIAL_FRIEND_LIST_GET_GID);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnGameUserSeqAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	GameUserSeqAck ans;
	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		::Logger::GETLOG()->ToAll(::Logger::DEBUG, "%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << ans.result
			<< static_cast<uint16_t>(ans.array_game_userseq_info.size());

	auto itr = ans.array_game_userseq_info.begin();
	for(; itr != ans.array_game_userseq_info.end(); ++itr)
	{
//		*pAck << itr->socialid.c_str()
		*pAck << itr->socialid
				<< itr->userseq;
	}
	pAck->MakePacket(CMD_SC_SOCIAL_INGAME_FRIEND_LIST_GET_GID);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnSocialFriendsAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	SocialFriendsAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	DEBUGLOG("$$ OnSocialFriendsAck seq : %d result : %d list_size : %d ",
			ans.seq, ans.result, s_UserTree.size());

	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	//DEBUGLOG("User main slot index : %d socialid : %s", pUser->GetUserInfo().main_slot_index, pUser->socialid);

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << ans.result
			<< static_cast<uint16_t>(ans.array_Friends.size());

	auto itr = ans.array_Friends.begin();
	for(; itr != ans.array_Friends.end(); ++itr)
	{
		* pAck << itr->userseq
				<< static_cast<uint8_t>(itr->no_play_period)
				<< static_cast<uint8_t>(itr->is_connect_requested)
				<< static_cast<uint8_t>(itr->is_heart_sent);
	}

	pAck->MakePacket(CMD_SC_SOCIAL_FRIEND_LIST_INFO);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnGameFriendsAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	GameFriendsAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	DEBUGLOG("$$ OnGameFriendsAck seq : %d result : %d list_size : %d ",
			ans.seq, ans.result, s_UserTree.size());

	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	//DEBUGLOG("User main slot index : %d socialid : %s", pUser->GetUserInfo().main_slot_index, pUser->socialid);

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%2d", ans.result, static_cast<uint8_t>(ans.array_Friends.size()));

	auto itr = ans.array_Friends.begin();
	for(; itr != ans.array_Friends.end(); ++itr)
	{
		* pAck << itr->userseq
				<< itr->nickname.c_str()
				<< itr->profile_url.c_str()
				<< static_cast<uint8_t>(itr->no_play_period)
				<< static_cast<uint8_t>(itr->is_connect_requested)
				<< static_cast<uint8_t>(itr->is_heart_sent);

	}

	pAck->MakePacket(CMD_SC_SOCIAL_INGAME_FRIEND_LIST_INFO);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnInviteNoAppAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	InviteNoAppAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << ans.result << ans.heart_count << ans.invite_count;

	pAck->MakePacket(CMD_SC_SOCIAL_INVITE_NOAPP_FRIEND_SM);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnSimpleFriendsAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	SimpleFriendsAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%c", ans.result, static_cast<uint8_t>(ans.array_Friends.size()));

	auto itr = ans.array_Friends.begin();
	for(; itr != ans.array_Friends.end(); ++itr)
	{
		* pAck << itr->userseq
				<< itr->score
				<< static_cast<uint8_t>(itr->is_connected)
				<< static_cast<uint8_t>(itr->buff_state)
				<< static_cast<uint8_t>(itr->heart_blocked)
				<< static_cast<uint8_t>(itr->invite_blocked)
				<< static_cast<uint8_t>(itr->profile_opend)
				<< static_cast<uint8_t>(itr->gender)
				<< static_cast<uint8_t>(itr->gender_open)
				<< itr->birthday.c_str()
				<< static_cast<uint8_t>(itr->birth_open)
				<< static_cast<uint16_t>(itr->server_id)
				<< static_cast<uint16_t>(itr->channel_id);

		if (1 == ans.is_medal)
		{
			* pAck	<< itr->gold
					<< itr->silver
					<< itr->bronze;
		}
	}

	if (1 == ans.is_medal)
		pAck->MakePacket(CMD_SC_SOCIAL_FRIEND_SIMPLE_LIST_V2);
	else
		pAck->MakePacket(CMD_SC_SOCIAL_FRIEND_SIMPLE_LIST);

	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnNewsCountAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket)
{
	NewsCountAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << ans.news_count;

	pAck->MakePacket(CMD_SC_SOCIAL_NEWS_COUNT);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnNewsAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	NewsInfoAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%c%c", ans.result, ans.isLastPage, static_cast<uint8_t>(ans.array_News.size()));

	auto itr = ans.array_News.begin();
	for(; itr != ans.array_News.end(); ++itr)
	{
		* pAck << itr->news_seq
				<< itr->user_seq
				<< static_cast<uint8_t>(itr->news_type)
				<< static_cast<uint32_t>(itr->heart_count)
				<< itr->nickname.c_str()
				<< itr->profile_url.c_str();
	}

	pAck->MakePacket(CMD_SC_SOCIAL_REQUEST_NEWS);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnMainListAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	MainListAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	int my_ranking = ans.my_ranking;
	int last_week_friend_count = ans.last_week_friend_count;
	if( 0 > ans.my_ranking )
	{
		my_ranking = pUser->GetUserInfo().score;
		last_week_friend_count = pUser->GetUserInfo().heart_blocked;
	}
	else
	{
		pUser->GetUserInfo().score = my_ranking;
		pUser->GetUserInfo().heart_blocked = last_week_friend_count;
		pUser->FlushCharacterInfoCache();
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

//	NResource::WeeklyRewardData::DATATREE & pRewardData = NResource::Static::InstancePtr()->GetWeeklyReward()->GetFly(pUser)->GetFlyTree();

	int isWeekRankShow = 0;

//	auto friend_iter = pRewardData.begin();
//	for(; friend_iter != pRewardData.end(); ++friend_iter)
//	{
//		if(1 == friend_iter->second->_TYPE)
//			break;
//	}

	time_t lastWeekRankFriendTime = pUser->GetUserInfo().array_Slot[static_cast<int>(NLogic::Reward::RewardType::LAST_WEEK_RANK_FRIEND)].reg_date;

//	if(lastWeekRankFriendTime < NLogic::NFunction::GetWeekInitTime()
//		&& friend_iter->second->_MIN <= last_week_friend_count)
	if (lastWeekRankFriendTime < NLogic::NFunction::GetWeekInitTime() && 5 <= last_week_friend_count)
	{
		isWeekRankShow = 1;
	}



//	auto rank_iter = pRewardData.rbegin();
//	for(; rank_iter != pRewardData.rend(); ++rank_iter)
//	{
//		if(0 == rank_iter->second->_TYPE)
//			break;
//	}

	time_t lastWeekRankRewardTime = pUser->GetUserInfo().array_Slot[static_cast<int>(NLogic::Reward::RewardType::LAST_WEEK_RANK_REWARD)].reg_date;

//	if(lastWeekRankRewardTime < NLogic::NFunction::GetWeekInitTime() && rank_iter->second->_MAX > my_ranking
//		&& friend_iter->second->_MIN <= last_week_friend_count)
	if(lastWeekRankRewardTime < NLogic::NFunction::GetWeekInitTime() && 20 >= my_ranking && 5 <= last_week_friend_count)
	{
		isWeekRankShow = 1;
	}


	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	* pAck << ans.result
			<< static_cast<uint8_t>(ans.heart_count)
			<< static_cast<uint8_t>(isWeekRankShow);

	pAck->MakePacket(CMD_SC_MAIN_FRIEND_LIST_DATA);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnUpdateProfileAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	UpdateProfileAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d", ans.result);

	pAck->MakePacket(CMD_SC_UPDATE_MY_PROFILE);
	pUser->Send(pAck);

	pUser->GetSocialInfo()->GetData()->_birthday = ans.birthday;
	pUser->GetSocialInfo()->GetData()->_isBirthdayOpen = ans.is_birthday_open;
	pUser->GetSocialInfo()->GetData()->_gender = ans.gender;
	pUser->GetSocialInfo()->GetData()->_isGenderOpen = ans.is_gender_open;
	pUser->GetSocialInfo()->GetData()->_profile_opened = ans.is_profile_open;
}

void
FriendsServer::Msg::OnUpdateStatusAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	UpdateStatusAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d", ans.result);

	pAck->MakePacket(CMD_SC_SOCIAL_UPDATE_MY_STATUS);
	pUser->Send(pAck);

	pUser->GetSocialInfo()->GetData()->_heart_blocked = ans.is_heart_block;
	pUser->GetSocialInfo()->GetData()->_invite_blocked = ans.is_invite_block;
}

void
FriendsServer::Msg::OnInviteBlockAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket)
{
	InviteBlockAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_invite_blocked = ans.invite_block;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << static_cast<uint16_t>(ans.result);
	pAck->MakePacket(CMD_SC_SOCIAL_UPDATE_INVITATION_BLOCK);
	pUser->Send(pAck);

}

void
FriendsServer::Msg::OnFriendShipBlockAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket)
{
	FriendShipBlockAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << static_cast<uint16_t>(ans.result);
	pAck->MakePacket(CMD_SC_SOCIAL_UPDATE_FRIENDSHIP_BLOCK);
	pUser->Send(pAck);

	pUser->GetSocialInfo()->GetData()->_heart_blocked = ans.heart_block;
}

void
FriendsServer::Msg::OnSendHeartAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	SendHeartAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%d", ans.result, ans.heart_count);

	pAck->MakePacket(CMD_SC_SOCIAL_SEND_HEART_SM);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnRecommendAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	RecommendAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	auto & usertree = GetUserTree();
	auto iter = usertree.find(ans.gid);
	if(usertree.end() == iter)
	{
		ans.result = ACK_OK;
		* pAck << ans.result << ans.gid << static_cast<uint32_t>(0)
				<< "" << "";
	}
	else
	{
		* pAck << ans.result << ans.gid << iter->second->GetUserInfo().score
				<< iter->second->GetUserInfo().nickname.c_str()
				<< iter->second->GetUserInfo().profile_url.c_str();
	}

	pAck->MakePacket(CMD_SC_SOCIAL_RECOMMEND_FRIEND_LIST);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnBoastAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	BoastAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%d", ans.result, ans.heart_count);

	pAck->MakePacket(CMD_SC_SOCIAL_BOAST);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnUseBuffAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	UseBuffAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	* pAck << ans.result << ans.buff_time << ans.heart_count;

	pAck->MakePacket(CMD_SC_SOCIAL_FRIEND_BUFF_SM);
	pUser->Send(pAck);

	NLogic::Buff::Data * data = pUser->GetBuff()->GetData(NLogic::Buff::BuffType::FRIEND);
	data->u16skill_tid = 190;
	data->u8skill_level = 1;
	data->s16skill_value = 5;
	data->u8type = static_cast<uint8_t>(NLogic::Buff::BuffType::FRIEND);
	data->_regdate = time(NULL) + ans.buff_time;
}

void
FriendsServer::Msg::OnGameFriendAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	GameFriendAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%d", ans.result, ans.heart_count);

	pAck->MakePacket(CMD_SC_SOCIAL_REQ_INGAME_FRIEND_SM);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnConfirmFriendAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	ConfirmFriendAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	if(ACK_OK == ans.is_accept)
	{
		FriendTypeModifySyn frmsg;
//		frmsg.socialid = pUser->GetSocialID().c_str();
//		char * pTemp;
//		frmsg.socialid = std::strtoll(pUser->GetSocialID().c_str(), &pTemp, pUser->GetSocialID().size());//.c_str();
		frmsg.socialid = atoll(pUser->GetSocialID().c_str());
		frmsg.gid = pUser->GetUserSeq();
		frmsg.type = 2; // 수락
		::ProjectZ::NProxy::SendFriendsServer(ans.gid, frmsg);
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%8d", ans.result, ans.news_seq);

	pAck->MakePacket(CMD_SC_SOCIAL_CONFIRM_FRIEND_REQ);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnRequestConnectAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	RequestConnectAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << ans.result << ans.heart_count;

	pAck->MakePacket(CMD_SC_SOCIAL_REQUEST_CONNECT_SM);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnConfirmNewsAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	ConfirmNewsAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	pAck->MsgCat("%2d%d%8d", ans.result, ans.heart_count, ans.news_seq);

	pAck->MakePacket(CMD_SC_SOCIAL_CONFIRM_NEWS);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnDeleteFriendAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	DeleteFriendAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << ans.result;

	pAck->MakePacket(CMD_SC_SOCIAL_DELETE_FRIEND);
	pUser->Send(pAck);

	// 상대방 트리에서 삭제
	if(ACK_OK == ans.result)
	{
		FriendTypeModifySyn frmsg;

		frmsg.gid = pUser->GetUserSeq();
		frmsg.type = 4;

		::ProjectZ::NProxy::SendFriendsServer(ans.gid, frmsg);
	}
}

void
FriendsServer::Msg::OnAllowFriendAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	AllowFriendAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	switch(ans.msgid)
	{
	case RecommendSyn::MSG_ID :
		if(1 != ans.is_allow)
		{
			::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
			* pAck << static_cast<uint16_t>(ACK_OK)
										<< static_cast<uint32_t>(0)		// gid
										<< static_cast<uint32_t>(0)		// score
										<< ""		// nickname
										<< "";		// profile_url

			pAck->MakePacket(CMD_SC_SOCIAL_RECOMMEND_FRIEND_LIST);
			pUser->Send(pAck);
		}
		else
		{
			RecommendSyn msg;
			msg.gid = ans.userseq;
			::ProjectZ::NProxy::SendFriendsServer(pUser->GetUserSeq(), msg);
		}
		break;

	case GameFriendSyn::MSG_ID :
		if(1 != ans.is_allow)
		{
			::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
			*pAck << static_cast<uint16_t>(ACK_MAX_FRIENDS_OTHER) << static_cast<uint32_t>(0);
			pAck->MakePacket(CMD_SC_SOCIAL_REQ_INGAME_FRIEND_SM);
			pUser->Send(pAck);
		}
		else
		{
			GameFriendSyn msg;
			msg.gid = ans.userseq;

			NResource::BalanceResource * balanceResource = NResource::Static::InstancePtr()->GetBalance();
			msg.heart_count_max = balanceResource->GetValue(pUser, EM_FRIEND_POINT_MAX);

			NResource::SocialRewardResource * socialReward = NResource::Static::InstancePtr()->GetSocialReward();
			NResource::SocialRewardData::Flyweight * rewardData = socialReward->GetFly(pUser, NResource::SocialRewardData::GameFriendReq);

			msg.send_heart_count = rewardData->_SEND_REWARD * rewardData->_IS_EVENT;
			msg.recv_heart_count = rewardData->_RECV_REWARD * rewardData->_IS_EVENT;
			msg.msg_type = rewardData->_MSG_TYPE;

			::ProjectZ::NProxy::SendFriendsServer(pUser->GetUserSeq(), msg);
		}
		break;

	case ConfirmFriendSyn::MSG_ID :
		if(1 != ans.is_allow)
		{
			::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
			*pAck << static_cast<uint16_t>(ACK_MAX_FRIENDS_OTHER) << ans.dummy;
			pAck->MakePacket(CMD_SC_SOCIAL_CONFIRM_FRIEND_REQ);
			pUser->Send(pAck);
		}
		else
		{
			ConfirmFriendSyn msg;
			msg.news_seq = ans.dummy;
			msg.is_accept = 1;
			msg.gid = ans.userseq;
			::ProjectZ::NProxy::SendFriendsServer(pUser->GetUserSeq(), msg);
		}
		break;
	}
}

void
FriendsServer::Msg::OnInviteCountAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	InviteCountAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << ans.result << ans.invite_count;
	pAck->MakePacket(CMD_SC_KAKAO_INVITATION_COUNT);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnFlushFRUserInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	FlushFRUserInfoAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}
	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}
}

void
SendFailGachyaBox(User * pUser, int16_t result)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << result
			<< static_cast<uint8_t>(0)
			<< static_cast<uint16_t>(0)
			<< static_cast<uint8_t>(0);
	pAck->MakePacket(CMD_SC_GACHYA_BOX);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnGachyaBoxAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	GachyaBoxAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

//	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
//	if(ACK_OK != ans.result)
//	{
//		SendFailGachyaBox(pUser, ans.result);
//		return;
//	}

//	NResource::FriendshipBoxResource * pFriendShipBox = NResource::Static::InstancePtr()->GetFriendshipBox();
//	if(NULL == pFriendShipBox)
//	{
//		SendFailGachyaBox(pUser, ACK_UNKNOWN_ERROR);
//		return;
//	}
//	NResource::FriendshipBoxData *pFriendShipBoxData = pFriendShipBox->GetFly(pUser);
//	int accRate = 0;
//	int randRate = rand() % pFriendShipBoxData->GetTotalRate();
//
//	auto iter = pFriendShipBoxData->GetTree().begin();
//	for(; iter != pFriendShipBoxData->GetTree().end(); ++iter)
//	{
//		accRate += iter->second->_RATE;
//
//		if (randRate < accRate)
//			break;
//	}
//
//	NResource::ChargeItemData::Flyweight * pChargeItemData = NResource::Static::InstancePtr()->GetChargeItem()->GetFly(pUser, iter->second->_TYPESEQ);
//	if(NULL == pChargeItemData)
//	{
//		SendFailGachyaBox(pUser, ACK_UNKNOWN_ERROR);
//		return;
//	}
//
//	NLogic::Item::Data clsData;
//	clsData.tid = pChargeItemData->_TID;
//	clsData.sub_type = pChargeItemData->_SHEET;
//	clsData.quantity = iter->second->_COUNT;
//	clsData.class_type = pChargeItemData->_CLASSTYPE;
//	NResource::Static::InstancePtr()->GetItemResource()->SetItemDataFromResource(pUser, clsData);
//
//	NLogic::MailBox::Mail::Data clsMailData;
//	clsMailData.send_user_seq		= 0;
//	clsMailData.send_user_nickname	= "GAMEVIL";
//	clsMailData.recv_user_seq		= pUser->GetUserInfo().userseq;
//
//	NResource::MailMessageResource::Flyweight *pFly = NResource::Static::InstancePtr()->GetMailMessageResource()->GetFly(NResource::MailMessageResource::EM_FRIENDSHIP_BOX_REWARD);
//	if(NULL == pFly)
//	{
//		SendFailGachyaBox(pUser, ACK_UNKNOWN_ERROR);
//		return;
//	}
//	clsMailData.message				= pFly->_MESSAGE.c_str();//"우정 상자 보상";
//	clsMailData.gift_status			= EM_GIFT_ITEM;
//	clsMailData.item				= clsData;
//
//	NLogic::MailBox::Mail * pMail	= NLogic::Static::InstancePtr()->GETMAILPOOL()->NEW();
//	pMail->Open_Normal(clsMailData, pUser);
//
//	if (false == pMail->InsertDatabaseMail())
//	{
//		NLogic::Static::InstancePtr()->GETMAILPOOL()->DEL(pMail);
//		DEBUGLOG("%s : false == pMail->InsertDatabaseMail()!! ITEM", __FUNCTION__);
//		SendFailGachyaBox(pUser, ACK_DB_ERROR);
//		return;
//	}
//	NLogic::Static::InstancePtr()->GETMAILPOOL()->DEL(pMail);
//
//	SubtractHeartCountSyn msg;
//	msg.msgid = msg.MSG_ID;
//
//	NResource::BalanceResource * balanceResource = NResource::Static::InstancePtr()->GetBalance();
//	msg.subtract_heart_count = balanceResource->GetValue(pUser, EM_FRIEND_POINT_MAX);
//	DEBUGLOG("우정포인트 차감 요청 %d", msg.subtract_heart_count);
//	::ProjectZ::NProxy::SendFriendsServer(pUser->GetUserSeq(), msg);
//
//	* pAck << static_cast<uint16_t>(ACK_OK)
//			<< static_cast<uint8_t>(pChargeItemData->_SHEET)
//			<< static_cast<uint16_t>(pChargeItemData->_TID)
//			<< static_cast<uint8_t>(iter->second->_COUNT);
//
//	pAck->MakePacket(CMD_SC_GACHYA_BOX);
//	pUser->Send(pAck);

}

void
FriendsServer::Msg::OnLastWeekRankInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	LastWeekRankInfoAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	NResource::WeeklyRewardResource * pWeeklyReward = NResource::Static::InstancePtr()->GetWeeklyReward();
	if ( false == pWeeklyReward->GetFly(pUser) )
	{
		return;
	}

	int myRanking = 0;
	int lastWeekFriendCount = 0;

	// -1 == ans.my_ranking
	// DB 에 있는 값 사용
	if( -1 == ans.my_ranking)
	{
		myRanking = pUser->GetUserInfo().score;
		lastWeekFriendCount = pUser->GetUserInfo().heart_blocked;
	}
	else
	{
	// -1 < ans.my_ranking
	// ans.my_ranking 사용
	// DB 에 ans.my_ranking 저장
		myRanking = ans.my_ranking;
		lastWeekFriendCount = ans.last_week_friend_count;

		pUser->GetUserInfo().score = ans.my_ranking;
		pUser->GetUserInfo().heart_blocked = ans.last_week_friend_count;

		pUser->FlushUserInfoCache();
	}

	time_t lastWeekRankRewardTime = pUser->GetUserInfo().array_Slot[static_cast<int>(NLogic::Reward::RewardType::LAST_WEEK_RANK_REWARD)].reg_date;
	DEBUGLOG("%s : lastRewardTime=%lld, weekInitTime=%lld, SEQ=%d", __FUNCTION__, lastWeekRankRewardTime, NLogic::NFunction::GetWeekInitTime(), ans.seq);

	// 저번주 랭킹 보상 여부
	int isLastWeekRankReward = 0;		// 0 : 보상 안받았음.(받을수 있음.) 1: 보상 받았음.
	if(lastWeekRankRewardTime < NLogic::NFunction::GetWeekInitTime())// && 0 < myRanking && 5 <= lastWeekFriendCount)
		isLastWeekRankReward = 0;
	else
		isLastWeekRankReward = 1;

	// 저번주 참여 친구 보상 여부
	int isLastWeekFriendReward = 0;
	time_t lastWeekFriendRewardTime = pUser->GetUserInfo().array_Slot[static_cast<int>(NLogic::Reward::RewardType::LAST_WEEK_RANK_FRIEND)].reg_date;
	if(lastWeekFriendRewardTime < NLogic::NFunction::GetWeekInitTime())// && 0 < myRanking && 5 <= lastWeekFriendCount)
		isLastWeekFriendReward = 0;
	else
		isLastWeekFriendReward = 1;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ACK_OK)
			<< static_cast<uint16_t>(myRanking)
			<< static_cast<uint16_t>(lastWeekFriendCount)
			<< ans.this_week_friend_count;

	DEBUGLOG("OnLastWeekRankInfoAck GID : %d , LastWeekRanking : %d , LastWeekFriendCount %d , WeekFriendCount %d",
			pUser->GetUserSeq(), myRanking, lastWeekFriendCount, ans.this_week_friend_count);

	* pAck << static_cast<uint8_t>(isLastWeekRankReward);
	* pAck << static_cast<uint8_t>(isLastWeekFriendReward);

	NResource::WeeklyRewardData::DATATREE & pRewardData = NResource::Static::InstancePtr()->GetWeeklyReward()->GetFly(pUser)->GetFlyTree();
	* pAck << static_cast<uint8_t>(pRewardData.size());

	std::for_each(pRewardData.begin(), pRewardData.end(), [&](std::pair<int, NResource::WeeklyRewardData::Flyweight*> pair) {
		* pAck << static_cast<uint8_t>(pair.second->_TYPE)
				<< static_cast<uint8_t>(pair.second->_MIN)
				<< static_cast<uint8_t>(pair.second->_MAX)
				<< static_cast<uint8_t>(pair.second->_TYPE)
				<< static_cast<uint32_t>(pair.second->_VALUE);

		if(0 == pair.second->_TYPE)
		{
			* pAck << static_cast<uint8_t>(-1)
									<< static_cast<uint8_t>(pair.second->_REWARD_SHEET_TYPE)
									<< static_cast<uint16_t>(pair.second->_REWARD_TID);
		}
		else if(1 == pair.second->_TYPE)
		{
			* pAck << static_cast<uint8_t>(0)
					<< static_cast<uint8_t>(pair.second->_REWARD_SHEET_TYPE)
					<< static_cast<uint16_t>(pair.second->_REWARD_TID);
		}
	});

	pAck->MakePacket(CMD_SC_LAST_WEEK_RANK_REWARD_INFO);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnGetHeartCountAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	GetHeartCountAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << ans.result << ans.heart_count;

	pAck->MakePacket(CMD_SC_SOCIAL_FRIEND_FRIENDSHIP_POINT);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnAddHeartCountAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket )
{
	AddHeartCountAck ans;

	const char* pBuf = pPacket->GetOffsetPtr();
	size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

	if(false == ans.Load(&pBuf, len))
	{
		return;
	}

	DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ans.MSG_ID, ans.seq);
	User * pUser = GetUser(ans.seq);
	if (NULL == pUser)
	{
		DEBUGLOG("%s User is null", __FUNCTION__);
		return;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ans.heart_count;
}

void
FriendsServer::Msg::OnSendStaminaAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket)
{
	SendStaminaAck ack;

    const char* pBuf = pPacket->GetOffsetPtr();
    size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

    if(false == ack.Load(&pBuf, len))
    {
        return;
    }

    DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ack.MSG_ID, ack.seq);

    User * pUser = GetUser(ack.seq);
    if (NULL == pUser)
    {
        DEBUGLOG("%s User is null", __FUNCTION__);
        return;
    }

    if (ack.result != ACK_OK)
    {
    	DEBUGLOG("%s : Response is Not OK! ack=%d", __FUNCTION__, ack.result);

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ack.result);
		pAck->MakePacket(CMD_SC_SOCIAL_SEND_STAMINA_SM);
		pUser->Send(pAck);

		return;
    }

	NLogic::Buff * pBuff = pUser->GetBuff();
	if (NULL == pBuff)
	{
		DEBUGLOG("%s : pBuff is NULL!!", __FUNCTION__);

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ACK_UNKNOWN_ERROR);
		pAck->MakePacket(CMD_SC_SOCIAL_SEND_STAMINA_SM);
		pUser->Send(pAck);

		return;
	}

	NLogic::Buff::Data * pBuffData = pBuff->GetData(NLogic::Buff::BuffType::FRIEND);
	if (NULL == pBuffData)
	{
		DEBUGLOG("%s : pBuffData is NULL!!", __FUNCTION__);

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ACK_UNKNOWN_ERROR);
		pAck->MakePacket(CMD_SC_SOCIAL_SEND_STAMINA_SM);
		pUser->Send(pAck);

		return;
	}

	pBuffData->u8type			= static_cast<uint8_t>(NLogic::Buff::BuffType::FRIEND);
	pBuffData->u16skill_tid		= 190;
	pBuffData->u8skill_level	= 1;
	pBuffData->s16skill_value	= 5;

	time_t curTime = time(NULL);

	// 버프 사용 시간이 지난 경우
	if (curTime > pBuffData->_regdate)
	{
		pBuffData->_regdate = curTime + 300;
	}
	else	// 버프 사용 시간이 지나지 않은 경우 누적
	{
		pBuffData->_regdate += 300;

		// 누적은 최대 1시간.
		if ( (pBuffData->_regdate - curTime) >= 3600 )
			pBuffData->_regdate = curTime + 3600;
	}

	// 응답
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ACK_OK);
	*pAck << static_cast<uint32_t>(pBuffData->_regdate - curTime);
	pAck->MakePacket(CMD_SC_SOCIAL_SEND_STAMINA_SM);
	pUser->Send(pAck);
}

void
FriendsServer::Msg::OnConfirmNewsV2Ack(Dispatcher::Session* pSession, ::Network::Packet * pPacket)
{
	ConfirmNewsV2Ack ack;

    const char* pBuf = pPacket->GetOffsetPtr();
    size_t len = pPacket->m_nEnd - pPacket->m_nOffset;

    if(false == ack.Load(&pBuf, len))
    {
        return;
    }

    DEBUGLOG("%s, MSG_ID : %d SEQ : %d", __FUNCTION__, ack.MSG_ID, ack.seq);

    User * pUser = GetUser(ack.seq);
    if (NULL == pUser)
    {
        DEBUGLOG("%s User is null", __FUNCTION__);
        return;
    }

    if (ack.result != ACK_OK && ack.result != ACK_NOT_RECV_STAMINA && ack.result != ACK_STAMINA_MAX_OVERFLOW)
    {
		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ack.result);
		pAck->MakePacket(CMD_SC_SOCIAL_CONFIRM_NEWS_V2);
		pUser->Send(pAck);

		return;
    }

    // 현재 스태미너 누적
	pUser->GetCharacterInfo().cur_stamina += ack.charge_stamina_count;
	if (pUser->GetCharacterInfo().cur_stamina > static_cast<uint32_t>(STAMINA_MAX_CHARGE))
	{
		pUser->GetCharacterInfo().cur_stamina = STAMINA_MAX_CHARGE;
	}

	// 하루동안 받은 스태미너 누적
	pUser->GetUserInfo().recv_stamina += ack.charge_stamina_count;
	if (pUser->GetUserInfo().recv_stamina > static_cast<uint32_t>(MAX_RECV_STAMINA))
	{
		pUser->GetUserInfo().recv_stamina = MAX_RECV_STAMINA;
	}

	pUser->GetSocialInfo()->GetData()->_heart_count = ack.heart_count;

    ::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
    *pAck << static_cast<int16_t>(ack.result);
    *pAck << static_cast<uint32_t>(ack.heart_count);
    *pAck << static_cast<uint32_t>(pUser->GetCharacterInfo().cur_stamina);
    *pAck << static_cast<uint64_t>(ack.news_seq);
    pAck->MakePacket(CMD_SC_SOCIAL_CONFIRM_NEWS_V2);
    pUser->Send(pAck);
}

FriendsServer::FriendsServer()
{
	_pSession = new Session;
	_pSession->SetState(new State());

	_pSession->SetOwner(this);

	_bConnect = false;
	_idx = -1;
}

FriendsServer::~FriendsServer() {
	delete _pSession->GetState();
	delete _pSession;
}

bool
FriendsServer::Connect(int idx, std::string strIP, int port)
{
	//::Network::Session::Info clsInfo;
	_clsInfo.eType = ::Network::Session::Info::SERVER;
	_clsInfo.ip = strIP.c_str();
	_clsInfo.port = port;
	_clsInfo.keepAliveTime = 3000 * 10;
	_idx = idx;

	bool bConnect = _pSession->Connect(_clsInfo);

	if (true == bConnect)
		_bConnect = true;

	return bConnect;
}

void
FriendsServer::OnDisconnect()
{
	auto tree = GetUserTree();
	auto itr = tree.begin();
	for ( ; itr != tree.end(); ++itr)
	{
		User * pUser = itr->second;
		if (NULL == pUser)
			continue;

		::ProjectZ::Session * pSession = pUser->GetSession();
		if (NULL == pSession)
			continue;

		NLogic::BackEndServerInfo * pBackEndServerInfo = pUser->GetBackEndServerInfo();
		if (NULL == pBackEndServerInfo)
			continue;

		if (pBackEndServerInfo->GetData()._friendsServerIndex != this->_idx)
			continue;

		//pSession->Close();

		User::State * pState = pUser->GetState();
		if (NULL != pState)
			pState->OnClose(pUser, true);
	}

	_bConnect = false;
	this->setTime();
}

bool
FriendsServer::OnTime(int id, void* param)
{
	_pSession = new Session;
	_pSession->SetState(new State());
	_pSession->SetOwner(this);

	bool bConnect = _pSession->Connect(_clsInfo);

	if (true == bConnect)
		_bConnect = true;
	else
	{
		// 타이머 재 등록...
		this->setTime();
	}

	return false;
}

void
FriendsServer::setTime()
{
	// 15 초 타이머 진행....
	::Dispatcher::Timer::Argument clsArgument(1000 * 15, 0, NULL, this);
	::Dispatcher::GETTIMER()->SetTimer(clsArgument);
}

} /*NProxy*/ } /*ProjectZ*/
